#ifndef INCLUDED_CFRAME_H
#define INCLUDED_CFRAME_H

#include "cfg.h"
#include "iframe.h"
#include "console.h"
#include "consoleplus.h"
#include <cstddef>
#include <string.h>

namespace cio {

class CFrame : public iFrame {
  struct {
    int row;
    int col;
  } position;
  int m_width;
  int m_height;

  bool visibility;
  void* hidden_area;

  bool hasBorder;
  char border[8];

  CFrame* parent;

  // private functions
  void setLine( char* str, char left, char fill, char right) const;
  void capture();

  public:
  CFrame( int l_row = -1,
          int l_col = -1,
          int l_width = -1,
          int l_height = -1,
          bool l_visibility = false,
          const char* l_border = C_BORDER_CHARS,
          CFrame* l_parent = (CFrame*)NULL):
    m_width(l_width),
    m_height(l_height),
    parent(l_parent),
    visibility(l_visibility),
    hasBorder(true),
    hidden_area(NULL)
  {
    memcpy(border, l_border, sizeof(border));
    position.row = l_row;
    position.col = l_col;
    if(l_height < 0) {
      m_height = console.getRows();
      m_width = console.getCols();
      position.row = 0;
      position.col = 0;
      hasBorder = false;
    }
  }

  ~CFrame() {
    if(hidden_area)
      release(&hidden_area);
  }

  // this should have been private ?
  // however I do not know another way of 
  // getting absrow
  int absrow() const;
  int abscol() const;

  // inherited virtual methods 
  void draw(int fn = C_FULL_FRAME);
  void move(CDirection dir);
  void hide(CDirection dir = C_STATIONARY);

  // new public methods
  void goMiddle();

  void bordered(bool l_border) { hasBorder = l_border;}
  bool bordered() const { return hasBorder; }

  void frame(CFrame* l_parent) { parent = l_parent;}
  CFrame* frame() const { return parent; }

  void row(int l_row) { position.row = l_row; }
  int row() const { return position.row; }

  void col(int l_col) { position.col = l_col; }
  int col() const { return position.col; } 

  void height(int l_height) { m_height = l_height; }
  int height() const { return m_height; }

  void width(int l_width) { m_width = l_width; }
  int width() const { return m_width; };

  void display(const char*);

  int edit(char* str, int fieldLen, bool* insertMode, int* offset, \
      int* cursor);

};

void move(iFrame& frame);

} // cio namespace ends

#endif
